package com.click.app.webapp.action;

import com.click.app.model.LaundryItem;
import com.click.app.model.LaundryRequest;
import com.click.app.model.LaundryRequestItem;
import com.click.app.model.LaundryType;
import com.click.app.model.ModelSize;
import com.click.app.model.PantDesign;
import com.click.app.model.SeamStorage;
import com.click.app.model.SizeRank;
import com.click.app.model.TradeMark;
import com.click.app.service.GenericManager;
import com.click.app.service.LaundryItemManager;
import com.click.app.service.LaundryRequestItemManager;
import com.click.app.service.PantDesignManager;
import com.click.app.service.SeamStorageManager;
import com.click.app.webapp.reportObjects.BodyRow;
import com.click.app.webapp.reportObjects.LaundryRequestTable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * @author Joel Chuca
 */
public class LaundryRequestItemAction extends BaseAction {

    private PantDesignManager pantDesignManager;
    private SeamStorageManager seamStorageManager;
    private LaundryRequestItemManager laundryRequestItemManager;
    private GenericManager<LaundryRequest, Long> laundryRequestManager;
    private GenericManager<TradeMark, Long> tradeMarkManager;
    private GenericManager<LaundryType, Long> laundryTypeManager;
    private GenericManager<SizeRank, Long> sizeRankManager;
    private LaundryItemManager laundryItemManager;
    private LaundryRequest laundryRequest;
    private LaundryRequestItem laundryRequestItem;
    //private SeamStorage seamStorage;
    private PantDesign pantDesign;
    private List laundryRequestItems;
    //private List seamStorages;
    private List<SeamStorage> seamStoragesAvailable;
    private List laundryTypes;
    private List pantDesigns;
    //private List pantDesignEnables;
    private Set<ModelSize> modelSizes;
    //private Set<ModelSize> modelSizeInputs;
    private List<LaundryItem> laundryItems;
    private String[] quantities;
    private Long id;
    private Long idLaundryRequest;
    private LaundryRequestTable laundryRequestTable;

    public void setLaundryRequestItemManager(LaundryRequestItemManager laundryRequestItemManager) {
        this.laundryRequestItemManager = laundryRequestItemManager;
    }

    public void setLaundryRequestManager(GenericManager<LaundryRequest, Long> laundryRequestManager) {
        this.laundryRequestManager = laundryRequestManager;
    }

    public void setLaundryTypeManager(GenericManager<LaundryType, Long> laundryTypeManager) {
        this.laundryTypeManager = laundryTypeManager;
    }

    public void setPantDesignManager(PantDesignManager pantDesignManager) {
        this.pantDesignManager = pantDesignManager;
    }

    public void setSeamStorageManager(SeamStorageManager seamStorageManager) {
        this.seamStorageManager = seamStorageManager;
    }

    public void setTrademarkManager(GenericManager<TradeMark, Long> trademarkManager) {
        this.tradeMarkManager = trademarkManager;
    }

    public void setSizeRankManager(GenericManager<SizeRank, Long> sizeRankManager) {
        this.sizeRankManager = sizeRankManager;
    }

    public void setLaundryItemManager(LaundryItemManager laundryItemManager) {
        this.laundryItemManager = laundryItemManager;
    }

    public List getLaundryRequestItems() {
        return laundryRequestItems;
    }

    public List getLaundryTypes() {
        return laundryTypes;
    }

    public List<LaundryItem> getLaundryItems() {
        return laundryItems;
    }

    public String[] getQuantities() {
        return quantities;
    }

    public void setQuantities(String[] quantities) {
        this.quantities = quantities;
    }

    /*
    public List getSeamStorages() {
    return seamStorages;
    }
     */
    public List getPantDesigns() {
        return pantDesigns;
    }

    public List<SeamStorage> getSeamStoragesAvailable() {
        return seamStoragesAvailable;
    }

    public Set<ModelSize> getModelSizes() {
        return modelSizes;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getIdLaundryRequest() {
        return idLaundryRequest;
    }

    public void setIdLaundryRequest(Long idLaundryRequest) {
        this.idLaundryRequest = idLaundryRequest;
    }

    public LaundryRequest getLaundryRequest() {
        return laundryRequest;
    }

    public void setLaundryRequest(LaundryRequest laundryRequest) {
        this.laundryRequest = laundryRequest;
    }

    public LaundryRequestItem getLaundryRequestItem() {
        return laundryRequestItem;
    }

    public void setLaundryRequestItem(LaundryRequestItem laundryRequestItem) {
        this.laundryRequestItem = laundryRequestItem;
    }

    public LaundryRequestTable getLaundryRequestTable() {
        return laundryRequestTable;
    }

    public PantDesign getPantDesign() {
        return pantDesign;
    }

    public void setPantDesign(PantDesign pantDesign) {
        this.pantDesign = pantDesign;
    }

    public String list() {
        System.out.println("Entroooooo 1");
        if (idLaundryRequest != null) {
            laundryRequest = laundryRequestManager.get(idLaundryRequest);
            getSession().setAttribute("laundryRequest", laundryRequest);
        } else {
            laundryRequest = ((LaundryRequest) getSession().getAttribute("laundryRequest"));
            System.out.println("Entroooooo 2");
        }

        if (laundryRequest != null) {
            //update
            laundryRequest = laundryRequestManager.get(laundryRequest.getId());
            modelSizes = sizeRankManager.get(laundryRequest.getSizeRank().getId()).getModelSizes();
            getSession().setAttribute("modelSizes", modelSizes);
            System.out.println("modelSizes: " + modelSizes);
            System.out.println("Entroooooo 3");
            laundryRequestTable = new LaundryRequestTable(laundryRequest.getLaundryRequestItems(), laundryItemManager, modelSizes);

        } else {
            System.out.println("laundryRequest is null");
            return ERROR;
        }
        return SUCCESS;
    }

    public String edit() {
        System.out.println("........... Start edit (laundryRequestItemAction) ...........");

        laundryRequest = ((LaundryRequest) getSession().getAttribute("laundryRequest"));
        pantDesigns = seamStorageManager.findByModelAndMaterial(laundryRequest.getTradeMark().getId());
        modelSizes = ((Set<ModelSize>) getSession().getAttribute("modelSizes"));
        laundryTypes = laundryTypeManager.getAll();

        if (id != null) {
            laundryRequestItem = laundryRequestItemManager.get(id);
            pantDesign = laundryRequestItem.getLaundryItems().get(0).getPantDesign();
            seamStoragesAvailable = seamStorageManager.findByPantDesignAndTradeMarkAndSizes(pantDesign, laundryRequest.getTradeMark().getId(), modelSizes);
            laundryItems = laundryItemManager.findByOrderSize(laundryRequestItem.getId());
            quantities = new String[modelSizes.size()];
            for (int i = 0; i < modelSizes.size(); i++) {
                quantities[i] = laundryItems.get(i).getQuantity() + "";
            }
            getSession().setAttribute("pantDesign", pantDesign);
            getSession().setAttribute("seamStoragesAvailable", seamStoragesAvailable);

        } else {
            laundryRequestItem = ((LaundryRequestItem) getSession().getAttribute("laundryRequestItem"));
            // verify if was sended to reload
            if (laundryRequestItem != null) {
                pantDesign = (PantDesign) getSession().getAttribute("pantDesign");
                seamStoragesAvailable = ((List<SeamStorage>) getSession().getAttribute("seamStoragesAvailable"));

                if (seamStoragesAvailable.size() == modelSizes.size()) {
                    quantities = new String[modelSizes.size()];
                    for (int i = 0; i < modelSizes.size(); i++) {
                        quantities[i] = seamStoragesAvailable.get(i).getStock() + "";
                    }
                } else {
                    System.out.println("SeamStoragesAvailable's size doesn't equal to modelSizes's size ");
                    return "error";
                }

            } else {
                laundryRequestItem = new LaundryRequestItem();
                laundryRequestItem.setQuantity(0);
                laundryRequestItem.setFailQuantity(0);
                laundryRequestItem.setUnitPrice(0f);
                laundryRequestItem.setFailUnitPrice(0f);
            }

        }
        System.out.println("........... End edit ...........");

        return SUCCESS;
    }

    public String save() {
        System.out.println("........... Start save RELOAD (laundryRequestItemAction) ...........");
        // verify correct dates of laundryRequestItem entity

        if (getRequest().getParameter("laundryRequestItem.unitPrice") != null &&
                getRequest().getParameter("laundryRequestItem.unitPrice").length() > 0) {
            laundryRequestItem.setUnitPrice(Float.parseFloat(getRequest().getParameter("laundryRequestItem.unitPrice")));
        }

        if (laundryRequestItem.getLaundryType() != null && laundryRequestItem.getLaundryType().getId() > 0) {
            LaundryType laundryType = laundryTypeManager.get(laundryRequestItem.getLaundryType().getId());
            laundryRequestItem.setUnitPrice(laundryType.getUnitPrice());
        }

        if (pantDesign != null && pantDesign.getId() > 0) {
            laundryRequest = ((LaundryRequest) getSession().getAttribute("laundryRequest"));
            pantDesign = pantDesignManager.get(pantDesign.getId());
            modelSizes = ((Set<ModelSize>) getSession().getAttribute("modelSizes"));
            seamStoragesAvailable = seamStorageManager.findByPantDesignAndTradeMarkAndSizes(pantDesign, laundryRequest.getTradeMark().getId(), modelSizes);
            getSession().setAttribute("pantDesign", pantDesign);
            getSession().setAttribute("seamStoragesAvailable", seamStoragesAvailable);
            System.out.println("seamStoragesAvailable: " + seamStoragesAvailable);
        } else {
            System.out.println("pantDesing: is null");
        }

        if (laundryRequestItem == null) {
            System.out.println("es nulo: " + laundryRequestItem);
        }
        getSession().setAttribute("laundryRequestItem", laundryRequestItem);
        System.out.println("........... End save RELOAD ...........");

        return "reload";
    }

    public String saveButton() throws Exception {

        if (cancel != null) {
            return CANCEL;
        }

        if (delete != null) {
            //return delete();
        }

        System.out.println("Quantities dates");
        for (int i = 0; i < quantities.length; i++) {
            System.out.println("quantity: " + quantities[i]);
        }


        Enumeration<String> en = getRequest().getParameterNames();
        while (en.hasMoreElements()) {
            String string = en.nextElement();
            System.out.println("Parameter " + string + ": " + getRequest().getParameter(string));
        }

        boolean isNew = false;
        isNew = (laundryRequestItem.getId() == null);

        String result = verifyInputDatas();
        if (result != null) {
            return result;
        }

        laundryRequestItem.setUnitPrice(Float.parseFloat(getRequest().getParameter("laundryRequestItem.unitPrice")));

        laundryRequest = (LaundryRequest) getSession().getAttribute("laundryRequest");

        if (!isNew) {
            // -------------  update old datas ------------
            LaundryRequestItem laundryRequestItemOld = laundryRequestItemManager.get(laundryRequestItem.getId());
            laundryItems = laundryItemManager.findByOrderSize(laundryRequestItemOld.getId());
            PantDesign pantDesignOld = laundryRequestItemOld.getLaundryItems().get(0).getPantDesign();
            modelSizes = ((Set<ModelSize>) getSession().getAttribute("modelSizes"));
            pantDesign = pantDesignManager.get(pantDesign.getId());
            seamStoragesAvailable = seamStorageManager.findByPantDesignAndTradeMarkAndSizes(pantDesign, laundryRequest.getTradeMark().getId(), modelSizes);

            // --- modify laudry request
            Float mountOld = laundryRequestItemOld.getTotalPrice();
            Integer quantityOld = laundryRequestItemOld.getQuantity();
            // ----------- verify if the actully quantities exceeds available stock ----------
            if (pantDesign.getId() == pantDesignOld.getId()) {
                Integer totalQuantity = 0;

                for (int i = 0; i < quantities.length; i++) {
                    Integer quantity = Integer.parseInt(quantities[i]);
                    Integer quantityStock = seamStoragesAvailable.get(i).getStock() + laundryItems.get(i).getQuantity();
                    System.out.println("quantityStock :" + quantityStock);
                    if (quantity > quantityStock) {
                        errorMessage("Update1: Quantity exceeded the stock available");
                        return "reload";
                    }
                    totalQuantity += quantity;
                }

                System.out.println("laundryRequestItemOld " + laundryRequestItemOld.getLaundryRequest());

                //laundryRequestItemOld.setLaundryRequest(laundryRequest);
                laundryRequestItemOld.setQuantity(totalQuantity);
                laundryRequestItemOld.setUnitPrice(laundryRequestItem.getUnitPrice());
                laundryRequestItemOld.setTotalPrice(laundryRequestItem.getUnitPrice() * totalQuantity);
                laundryRequestItemOld = laundryRequestItemManager.save(laundryRequestItemOld);

                for (int i = 0; i < quantities.length; i++) {
                    Integer quantity = Integer.parseInt(quantities[i]);
                    Integer quantityDif = quantity - laundryItems.get(i).getQuantity();
                    laundryItems.get(i).setQuantity(quantity);
                    seamStoragesAvailable.get(i).decrementStock(quantityDif);
                    laundryItemManager.save(laundryItems.get(i));
                    seamStorageManager.save(seamStoragesAvailable.get(i));
                }
            } else {

                Integer totalQuantity = 0;
                for (int i = 0; i < quantities.length; i++) {
                    Integer quantity = Integer.parseInt(quantities[i]);
                    if (quantity > seamStoragesAvailable.get(i).getStock()) {
                        saveMessage("Update2: Quantity exceded the stock available");
                        return "reload";
                    }
                    totalQuantity += quantity;
                }

                laundryRequestItemOld.setQuantity(totalQuantity);
                laundryRequestItemOld.setUnitPrice(laundryRequestItem.getUnitPrice());
                laundryRequestItemOld.setTotalPrice(laundryRequestItem.getUnitPrice() * totalQuantity);
                laundryRequestItemOld = laundryRequestItemManager.save(laundryRequestItemOld);

                List<SeamStorage> seamStoragesAvailableOld = seamStorageManager.findByPantDesignAndTradeMarkAndSizes(pantDesign, laundryRequest.getTradeMark().getId(), modelSizes);
                for (int i = 0; i < quantities.length; i++) {
                    Integer quantity = Integer.parseInt(quantities[i]);
                    seamStoragesAvailableOld.get(i).incrementStock(laundryItems.get(i).getQuantity());
                    laundryItems.get(i).setPantDesign(pantDesign);
                    laundryItems.get(i).setQuantity(quantity);
                    seamStoragesAvailable.get(i).decrementStock(quantity);
                    laundryItemManager.save(laundryItems.get(i));
                    seamStorageManager.save(seamStoragesAvailable.get(i));
                    seamStorageManager.save(seamStoragesAvailableOld.get(i));
                }
            }

            laundryRequest = laundryRequestManager.get(laundryRequest.getId());
            laundryRequest.setTotalPrice(laundryRequest.getTotalPrice() - mountOld + laundryRequestItemOld.getTotalPrice());
            laundryRequest.setQuantity(laundryRequest.getQuantity() - quantityOld + laundryRequestItemOld.getQuantity());
            laundryRequest = laundryRequestManager.save(laundryRequest);

        } else {
            Integer totalQuantity = 0;
            seamStoragesAvailable = ((List<SeamStorage>) getSession().getAttribute("seamStoragesAvailable"));
            for (int i = 0; i < quantities.length; i++) {
                Integer quantity = Integer.parseInt(quantities[i]);
                if (quantity > seamStoragesAvailable.get(i).getStock()) {
                    saveMessage("Quantity exceded the stock available");
                    return "reload";
                } else if (quantity < 0) {
                    saveMessage("Quantity incorrect: the quantity is less than zero");
                    return "reload";
                }
                totalQuantity += quantity;
            }


            laundryRequestItem.setQuantity(totalQuantity);
            laundryRequestItem.setTotalPrice(laundryRequestItem.getUnitPrice() * totalQuantity);
            laundryRequestItem.setFailQuantity(0);
            laundryRequestItem.setFailUnitPrice(0f);
            laundryRequestItem.setFailTotalPrice(0f);
            laundryRequestItem.setLaundryRequest(laundryRequest);
            laundryRequestItem = laundryRequestItemManager.save(laundryRequestItem);

            laundryItems = new ArrayList<LaundryItem>();
            for (int i = 0; i < quantities.length; i++) {
                SeamStorage seamStorage = seamStoragesAvailable.get(i);
                Integer quantity = Integer.parseInt(quantities[i]);
                LaundryItem laundryItem = new LaundryItem();
                laundryItem.setPantDesign(seamStorage.getPantDesign());
                laundryItem.setQuantity(quantity);
                laundryItem.setFailQuantity(0);
                laundryItem.setLaundryRequestItem(laundryRequestItem);
                laundryItem = laundryItemManager.save(laundryItem);
                seamStorage.decrementStock(quantity);
                seamStorage = seamStorageManager.save(seamStorage);
            }

            laundryRequest = laundryRequestManager.get(laundryRequest.getId());
            laundryRequest.setTotalPrice(laundryRequest.getTotalPrice() + laundryRequestItem.getTotalPrice());
            laundryRequest.setQuantity(laundryRequest.getQuantity() + laundryRequestItem.getQuantity());
            laundryRequest = laundryRequestManager.save(laundryRequest);
        }

        getSession().setAttribute("laundryRequest", laundryRequest);
        getSession().setAttribute("pantDesign", null);
        getSession().setAttribute("laundryRequestItem", null);
        getSession().setAttribute("seamStoragesAvailable", null);

        if (isNew) {
            saveMessage(getText("laundryRequestItem.added"));
            return SUCCESS;
        } else {
            saveMessage(getText("laundryRequestItem.updated"));
            return INPUT;
        }
    }

    public String delete() {

        laundryRequest = (LaundryRequest) getSession().getAttribute("laundryRequest");
        laundryRequestItem = laundryRequestItemManager.get(laundryRequestItem.getId());        
        //pantDesign = laundryItems.get(0).getPantDesign();
        
        for (LaundryItem laundryItem : laundryRequestItem.getLaundryItems()) {
            SeamStorage seamStorage = seamStorageManager.findByPantDesignAndTradeMark(laundryItem.getPantDesign().getId(), laundryRequest.getTradeMark().getId()).get(0);
            seamStorage.incrementStock(laundryItem.getQuantity());
            seamStorage = seamStorageManager.save(seamStorage);
        }

        laundryRequest = laundryRequestManager.get(laundryRequest.getId());
        laundryRequest.setQuantity(laundryRequest.getQuantity()-laundryRequestItem.getQuantity());
        laundryRequest.setTotalPrice(laundryRequest.getTotalPrice() - laundryRequestItem.getTotalPrice());
        laundryRequest = laundryRequestManager.save(laundryRequest);

        // this sentence delete laundryRequestItem whith its laundryItems
        laundryRequestItemManager.remove(laundryRequestItem.getId());
        
        getSession().setAttribute("pantDesign", null);
        getSession().setAttribute("laundryRequestItem", null);

        saveMessage(getText("laundryRequestItem.deleted"));

        return "delete";
    }

    public String verifyInputDatas() {
        String result = null;

        try {
            for (int i = 0; i < quantities.length; i++) {
                Integer quantity = Integer.parseInt(quantities[i]);
            }

        } catch (Exception e) {
            System.out.println("LaundryRequestItemAction exception: " + e.getMessage());
            saveMessage("Quantity incorrect: the number does't have the format correct");
            result = "reload";
        }

        if (!(laundryRequestItem.getLaundryType() != null && laundryRequestItem.getLaundryType().getId() > 0)) {
            saveMessage("Laundry Type wasn't selected");
            result = "reload";
        }

        if (laundryRequestItem.getUnitPrice() == null) {
            saveMessage(getText("laundryRequestItemRequired.unitPrice"));
            result = "reload";
        } else {
            if (laundryRequestItem.getUnitPrice() < 0.001) {
                saveMessage(getText("laundryRequestItemRequired.unitPrice"));
                result = "reload";
            }
        }

        return result;
    }

    public String help() {
        return SUCCESS;
    }

    public String finalizeLaundryRequestItem() {
        getSession().setAttribute("laundryRequest", null);
        getSession().setAttribute("laundryRequestItem", null);
        getSession().setAttribute("pantDesign", null);
        return SUCCESS;
    }
}
